package jaux.tank.service.system.impl;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import jaux.tank.bean.constant.cache.Cache;
import jaux.tank.bean.constant.cache.CacheKey;
import jaux.tank.bean.constant.state.ManagerStatus;
import jaux.tank.bean.constant.state.MenuStatus;
import jaux.tank.bean.entity.system.Cfg;
import jaux.tank.bean.entity.system.Dept;
import jaux.tank.bean.entity.system.Dict;
import jaux.tank.bean.entity.system.Menu;
import jaux.tank.bean.entity.system.Notice;
import jaux.tank.bean.entity.system.User;
import jaux.tank.bean.vo.DictVo;
import jaux.tank.bean.vo.SpringContextHolder;
import jaux.tank.dao.system.CfgRepository;
import jaux.tank.dao.system.DeptRepository;
import jaux.tank.dao.system.DictRepository;
import jaux.tank.dao.system.MenuRepository;
import jaux.tank.dao.system.RoleRepository;
import jaux.tank.dao.system.SysNoticeRepository;
import jaux.tank.dao.system.UserRepository;
import jaux.tank.service.system.IConstantFactory;
import jaux.tank.service.system.LogObjectHolder;
import jaux.tank.utils.StrKit;
import jaux.tank.utils.ToolUtil;


/**
 * 常量的生产工厂
 *
 * @date 2017年2月13日 下午10:55:21
 */
@Component
@DependsOn("springContextHolder")
@CacheConfig
public class ConstantFactory implements IConstantFactory {
    private RoleRepository roleRepository = SpringContextHolder.getBean(RoleRepository.class);
    private DeptRepository deptRepository = SpringContextHolder.getBean(DeptRepository.class);
    private DictRepository dictRepository = SpringContextHolder.getBean(DictRepository.class);
    private UserRepository userRepository = SpringContextHolder.getBean(UserRepository.class);
    private MenuRepository menuRepository = SpringContextHolder.getBean(MenuRepository.class);
    private SysNoticeRepository sysNoticeRepository = SpringContextHolder.getBean(SysNoticeRepository.class);
    private CfgRepository cfgRepository = SpringContextHolder.getBean(CfgRepository.class);

    public static IConstantFactory me() {
        return SpringContextHolder.getBean("constantFactory");
    }
    /**
     * 根据用户id获取用户名称
     *
     * @Date 2017/5/9 23:41
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.SYS_USER_NAME + "'+#userId")
    public String getUserNameById(String userId) {
        User user = userRepository.findById(userId).orElse(null);
        if (user != null) {
            return  user.getName();
        } else {
            return "--";
        }
    }

    /**
     * 根据用户id获取用户账号
     *
     * @date 2017年5月16日21:55:371
     */
    @Override
    public String getUserAccountById(String userId) {
        User user = userRepository.findById(userId).orElse(null);
        if (user != null) {
            return user.getAccount();
        } else {
            return "--";
        }
    }

    /**
     * 通过角色ids获取角色名称
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.ROLES_NAME + "'+#roleIds")
    public String getRoleName(String roleIds) {
        String[] roles = roleIds.split(",");
        StringBuilder sb = new StringBuilder();
        for (String role : roles) {
            roleRepository.findById(role)
            		.filter(roleObj->ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getName()))
            		.ifPresent(roleObj->sb.append(roleObj.getName()).append(","));
        }
        return  StrKit.removeSuffix(sb.toString(), ",");
    }

    /**
     * 通过角色id获取角色名称
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.SINGLE_ROLE_NAME + "'+#roleId")
    public String getSingleRoleName(String roleId) {
        if (roleId == null || "".equals(roleId)) {
            return "--";
        }
        return roleRepository.findById(roleId)
        		.filter(roleObj->ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getName()))
        		.map(role->role.getName())
        		.orElse("");
    }

    /**
     * 通过角色id获取角色英文名称
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.SINGLE_ROLE_TIP + "'+#roleId")
    public String getSingleRoleTip(String roleId) {
        if (roleId == null ||"".equals( roleId)) {
            return "--";
        }
        return roleRepository.findById(roleId)
        		.filter(roleObj->ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getName()))
        		.map(role->role.getTips())
        		.orElse("");
    }

    /**
     * 获取部门名称
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.DEPT_NAME + "'+#deptId")
    public String getDeptName(String deptId) {
        Optional<Dept> dept = deptRepository.findById(deptId);
        if (dept.isPresent() && ToolUtil.isNotEmpty(dept.get().getFullname())) {
            return   dept.get().getFullname();
        }
        return "";
    }

    /**
     * 获取菜单的名称们(多个)
     */
    @Override
    public String getMenuNames(String menuIds) {
        String[] menus = menuIds.split(",");
        StringBuilder sb = new StringBuilder();
        for (String menu : menus) {
            Menu menuObj = menuRepository.findById(menu).orElse(null);
            if (menuObj!=null && ToolUtil.isNotEmpty(menuObj.getName())) {
                sb.append(menuObj.getName()).append(",");
            }
        }
        return StrKit.removeSuffix(sb.toString(), ",");
    }

    /**
     * 获取菜单名称
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.MENU_NAME + "'+#menuId")
    public String getMenuName(String menuId) {
        if (ToolUtil.isEmpty(menuId)) {
            return "";
        } else {
            Menu menu = menuRepository.findById(menuId).orElse(null);
            if (menu == null) {
                return "";
            } else {
                return menu.getName();
            }
        }
    }

    /**
     * 获取菜单名称通过编号
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.MENU_NAME + "'+#code")
    public String getMenuNameByCode(String code) {
        if (ToolUtil.isEmpty(code)) {
            return "";
        } else {
            Menu menu = menuRepository.findByCode(code);
            if (menu == null) {
                return "";
            } else {
                return menu.getName();
            }
        }
    }
    @Override
    public List<DictVo> findByDictName(String dictName) {
        Dict dictParent = dictRepository.findByName(dictName);
        List<DictVo> list = new ArrayList<DictVo>();
        if(dictParent==null){
            return list;
        }
        List<Dict> dicts = dictRepository.findByPid(dictParent.getId());
        for(int i=0;i<dicts.size();i++){
            Dict dict = dicts.get(i);
            DictVo dictVo = new DictVo(dict.getNum(),dict.getName());
            list.add(dictVo);
        }
        return list;
    }
    /**
     * 获取字典名称
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.DICT_NAME + "'+#dictId")
    public String getDictName(String dictId) {
        if (ToolUtil.isEmpty(dictId)) {
            return "";
        } else {
            Dict dict = dictRepository.findById(dictId).orElse(null);
            if (dict == null) {
                return "";
            } else {
                return dict.getName();
            }
        }
    }

    /**
     * 获取通知标题
     */
    @Override
    public String getNoticeTitle(String dictId) {
        if (ToolUtil.isEmpty(dictId)) {
            return "";
        } else {
            Notice notice = sysNoticeRepository.findById(dictId).orElse(null);
            if (notice == null) {
                return "";
            } else {
                return notice.getTitle();
            }
        }
    }

    /**
     * 根据字典名称和字典中的值获取对应的名称
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.DICT_NAME + "'+#name+#val")
    public String getDictsByName(String name, String val) {
        Dict temp = new Dict();
        temp.setName(name);
        Dict dict = dictRepository.findByName(name);
        if (dict == null) {
            return "";
        } else {
            List<Dict> dicts = dictRepository.findByPid(dict.getId());
            for (Dict item : dicts) {
                if (item.getNum() != null && item.getNum().equals(val)) {
                    return  item.getName();
                }
            }
            return "";
        }
    }

    /**
     * 获取性别名称
     */
    @Override
    public String getSexName(Integer sex) {
        return me().getDictsByName("性别", String.valueOf(sex));
    }

    @Override
    public String getCardTypeName(String cardType) {
        return getDictsByName("银行卡类型",cardType);
    }

    @Override
    public String getIdCardTypeName(String cardType) {
        return getDictsByName("证件类型",cardType);
    }

    @Override
    public String getRelationName(String relation) {
        return getDictsByName("联系人关系",relation);
    }

    /**
     * 获取用户登录状态
     */
    @Override
    public String getStatusName(Integer status) {
        return ManagerStatus.valueOf(status);
    }

    /**
     * 获取菜单状态
     */
    @Override
    public String getMenuStatusName(Integer status) {
        return MenuStatus.valueOf(status);
    }

    /**
     * 查询字典
     */
    @Override
    public List<Dict> findInDict(String id) {
        if (ToolUtil.isEmpty(id)) {
            return null;
        } else {
            List<Dict> dicts = dictRepository.findByPid( id);
            if (dicts == null || dicts.size() == 0) {
                return null;
            } else {
                return dicts;
            }
        }
    }

    /**
     * 获取被缓存的对象(用户删除业务)
     */
    @Override
    public String getCacheObject(String para) {
        return LogObjectHolder.me().get().toString();
    }

    /**
     * 获取子部门id
     */
    @Override
    public List<String> getSubDeptId(String deptid) {

        List<Dept> depts = this.deptRepository.findByParentDeptId( "%[" + deptid + "]%");

        ArrayList<String> deptids = new ArrayList<>();

        if(depts != null && depts.size() > 0){
            for (Dept dept : depts) {
                deptids.add(dept.getId());
            }
        }

        return deptids;
    }

    /**
     * 获取所有父部门id
     */
    @Override
    public List<String> getParentDeptIds(String deptid) {
    	List<String> parentDeptIds = new LinkedList<>();
        deptRepository.findById(deptid).ifPresent(dept->{
        	
        	if(dept.getParentDept()!=null) {
        		parentDeptIds.add(dept.getParentDept().getId());
        		parentDeptIds.addAll(getParentDeptIds(dept.getParentDept().getId()));
        	}
        });
    	return parentDeptIds;
    }


    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.DIC_ALL + "'+#pname")
    public List<Dict> getDicts(String pname) {

        Dict dict = dictRepository.findByName(pname);
        return dictRepository.findByPid(dict.getId());
    }
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.CFG + "'+#cfgName")
    public String getCfg(String cfgName){
        Cfg entity  = cfgRepository.findByCfgName(cfgName);
        if(entity==null)
        	return null;
       return  entity.getCfgValue();
    }

}
